
#ifndef Lines_AnimatedEntity_h
#define Lines_AnimatedEntity_h

#include "Vector3.h"
#include "Texture.h"
#include "Entity.h"
#include "RenderableEntity.h"
#include <string>
#include <map>
#include <vector>

typedef struct
{
    // each character can have multiple animated textures, so a number is needed to identify each texture
    int id;
    std::string name;
    Texture* texture;
    int columns;
    int rows;
    float frameWidth;
    float frameHeight;
    float frameWidthUV;
    float frameHeightUV;
} sAnimatedTexture;

typedef struct
{
    std::string name;
    float probability;
}sRandomAction;

class AnimationAction
{
public:
    // from XML
    std::string name;
    std::string from;
    std::string to;
    int initialFrame;
    int endFrame;
    float FPS;
    bool loops;
    int textureId;
    std::string playAtEnd;
    
    bool playRandom;
    float playRandomMin;
    float playRandomMax;
    std::vector<sRandomAction> randomAction;
    
    // calculated from XML data
    int totalFrames;
    
    void initialize()
    {
        totalFrames = endFrame - initialFrame + 1;
    }
    
    float getDuration()
    {
        return (endFrame - initialFrame) * (1 / FPS);
    }
};

typedef struct
{
    bool idleOffset;
    std::map< std::string, AnimationAction*> actions;
    std::vector<sAnimatedTexture> animatedTextures;
} sAnimatedEntityData;

#define FRAME_TIME 0.2f

class AnimatedEntity : public RenderableEntity
{
public:
    std::string actionState;
    float actionTimer;
    int currentTextureId;
    int currentFrame;
    bool avoidDelete;
    
    Vector2 paintMask;
    
    // random action
    float nextRandomActionTime;
    
    // to avoid loading every time for the same animated entities the same actions and textures, use a common pool
    static std::map< std::string, sAnimatedEntityData> datas;
    // ...but keep an instance pointer for the actions and animated textures for easing the use
    std::map< std::string, AnimationAction*> actions;
    std::vector<sAnimatedTexture> animatedTextures;
    
    float animationSpeed;
    
    AnimatedEntity(std::string entityName, Vector2 position);
    
    static void unload();
    
    Vector2 getFrameSize();
    
    
    std::string getCurrentAction();
    
    void playAction(std::string newAction, bool forcePlay = false, float animationSpeed = 1.0f);
    
    // reads xml and loads textures and actions for this animated entity. Can be called from outside this class
    void readXML(std::string entityName);
    
    void die();
    
    void update();
    void render();
    
//    void deleteEntity();
//    void requestDelete(bool force = false);
};

#endif
